import { Body, Controller, Get, Param, Post, Query, UseGuards } from '@nestjs/common';
import { AuthGuard } from '@nestjs/passport';
import { ApiOperation, ApiTags } from '@nestjs/swagger';
import { ApplyService, WorkflowData } from './apply.service';
import { CurrentUser } from 'src/user/user.decorator';
import { UserSys } from 'src/user/userSys.entity';
import { FindOptionsWhere, In } from 'typeorm';
import { ApplicationStatus, Apply } from './apply.entity';
import { Workflow, WorkflowType } from './workflow.entity';
import { RoleEnum } from 'src/role/role.enum';
import { UseLog } from 'src/log/useLog.decorator';

@Controller('api/apply')
@ApiTags("申请")
@UseGuards(AuthGuard("jwt"))
export class ApplyController {
    constructor(
        private readonly applyService: ApplyService
    ) { }

    @Get("getmine")
    @ApiOperation({ summary: "获取我的申请" })
    async getmine(@CurrentUser() user: UserSys) {
        const data = await this.applyService.apply.find({
            where: {
                user: {
                    id: user.id
                }
            },
            relations: ["current"],
        })
        const types = [...data.reduce((set, { name }) => {
            set.add(name);
            return set;
        }, new Set<string>())]
        const workflows = {};
        for (const name of types) {
            workflows[name] = this.applyService.list2tree(await this.applyService.workflow.find({ where: { name }, relations: ["next"] }))
        }
        return data.map((e) => ({
            ...e,
            workflow: workflows[e.name]
        }))
    }

    @Get("attendance/get")
    @ApiOperation({ summary: "获取我的审批" })
    async getoverflow(
        @CurrentUser() user: UserSys,
        @Query("type") type?: string
    ) {
        const where: FindOptionsWhere<Apply> = {
            system: { id: user.system.id },
        }
        if (!!type) where.name = type;
        const result = await this.applyService.apply.find({
            relations: ["system", "current", "user", "user.dept"],
            order: { id: "desc" },
            where
        })
        return result.filter(({ status, name, current, ...rest }) => {
            //显示已完成
            if (status === ApplicationStatus.finished) return true;
            const index = WorkflowData[name].findIndex((e) => {
                if (e.type === WorkflowType.user) {
                    return user.role === e.value
                }
                if (e.type === WorkflowType.dept) {
                    return user.dept?.deptRole === e.value
                }
            })
            //不显示职位比自己高的
            const userIndex = WorkflowData[name].findIndex((e) => {
                if (e.type === WorkflowType.user) {
                    return rest.user.role === e.value
                }
                if (e.type === WorkflowType.dept) {
                    return rest.user.dept?.deptRole === e.value
                }
            })
            if (userIndex > index) return false;
            return index <= WorkflowData[name].findIndex(e => {
                if (e.type === WorkflowType.user) {
                    return current.userRole === e.value
                }
                if (e.type === WorkflowType.dept) {
                    return current.deptRole === e.value
                }
            })
        }).map((item) => {
            if (item.status === ApplicationStatus.finished) return item
            const index = WorkflowData[item.name].findIndex((e) => {
                if (e.type === WorkflowType.user) {
                    return user.role === e.value
                }
                if (e.type === WorkflowType.dept) {
                    return user.dept?.deptRole === e.value
                }
            })
            const curIndex = WorkflowData[item.name].findIndex(e => {
                if (e.type === WorkflowType.user) {
                    return item.current.userRole === e.value
                }
                if (e.type === WorkflowType.dept) {
                    return item.current.deptRole === e.value
                }
            })
            if (index === curIndex) {
                return { ...item, type: "待我审批" }
            }
            if (index < curIndex) return { ...item, type: "已审批" }
        })

        // const current: FindOptionsWhere<Workflow>[] = [{
        //     type: WorkflowType.user,
        //     userRole: user.role
        // }]
        // if (!!user.dept) {
        //     current.push({
        //         type: WorkflowType.dept,
        //         deptRole: user.dept?.deptRole
        //     })
        // }
        // const where: FindOptionsWhere<Apply> = {
        //     system: { id: user.system.id },
        //     // status: ApplicationStatus.applying,
        //     // current
        // }
        // if (!!type) where.name = type;
        // const result = await this.applyService.apply.find({
        //     where,
        //     relations: ["system", "current", "user", "user.dept"],
        //     order: { id: "desc" }
        // })
        // return { result, WorkflowData }
        // return result.filter(e => {
        //     if (e.current.type === WorkflowType.user) {
        //         if (e.current.userRole === RoleEnum.manager) {
        //             return e.user.dept?.id === user.dept?.id
        //         }
        //     }
        //     return true;
        // })
    }

    @Post("add")
    @ApiOperation({ summary: "添加申请" })
    async add(
        @Body() { type, data, comment },
        @CurrentUser() user: UserSys
    ) {
        return this.applyService.create(type, user, JSON.stringify(data), comment);
    }
    @Post("set")
    @UseLog("审批")
    async set(
        @CurrentUser() user: UserSys,
        @Body() { ids, operation, comment }
    ) {
        const bool = operation == "true"
        const entitys = await this.applyService.apply.find({
            where: {
                id: In(ids)
            },
            relations: ["current", "current.next", "user", "user.system", "user.dept"]
        })
        for (const entity of entitys) {
            if (bool) {
                entity.current = entity.current.next;
                if (!entity.current || entity.current.userRole === RoleEnum.boos) {
                    //结束
                    entity.status = ApplicationStatus.finished
                    await this.applyService.finish(entity);
                }
            } else {
                entity.status = ApplicationStatus.rejected
                entity.comment = comment
            }
            await this.applyService.apply.save(entity);
        }
    }

    @Get(":id/del")
    @ApiOperation({ summary: "删除申请" })
    del(
        @CurrentUser() user: UserSys,
        @Param("id") id: number
    ) {
        return this.applyService.apply.delete({
            id,
            user: {
                id: user.id
            }
        })
    }
}
